package com.qdlc.p2p.biz.service;

import java.util.Date;
import java.util.List;

import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.BorrowMortgage;
import com.qdlc.p2p.dal.dto.BorrowRepayment;
import com.qdlc.p2p.dal.dto.BorrowUpload;
import com.qdlc.p2p.dal.dto.Operator;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.BorrowModel;
import com.qdlc.p2p.dal.model.BorrowRepaymentModel;

/**
 * 标Service
 *
 * @author xx
 * @version 2.0
 * @since 2014年4月4日
 */
public interface BorrowService {

    /**
     * 新增
     *
     * @param model
     * @param user
     * @param list
     */
    Borrow save(BorrowModel model, User user, List<BorrowUpload> list);

    /**
     * 分页
     *
     * @param model
     * @return
     */
    PageDataList<BorrowModel> list(BorrowModel model);

    /**
     * <p>后台查询</p>
     *
     * @param model
     * @return
     * @author 原系统 2016年2月1日 下午4:09:01
     * @modificationHistory=========================逻辑或功能性重大变更记录
     * @modify by user: Kaiju Zhao 2016年2月1日 下午4:09:01
     * @modify by reason: 规范代码
     */
    PageDataList<BorrowModel> manageList(BorrowModel model);

    /**
     * 撤回标
     *
     * @param borrow
     * @return Borrow
     */
    void cancel(Borrow borrow) throws Exception;

    /**
     * 已登记未确认的借款标的取消
     *
     * @param borrow
     * @return Borrow
     */
    void borrowCancel(Borrow borrow) throws Exception;

    /**
     * 修改标
     *
     * @param borrow
     */
    void update(Borrow borrow);

    /**
     * 通过主键获得borrow实体类
     *
     * @param id
     * @return
     */
    Borrow find(long id);

    /**
     * 通过唯一标识符uuid获得borrow实体类
     *
     * @param uuid
     * @return
     */
    public Borrow find(String uuid);

    /**
     * 还款操作
     *
     * @param borrowRepayment
     */
    void doRepay(BorrowRepayment borrowRepayment);

    /**
     * 提前还款操作
     *
     * @param borrowRepayment
     */
    void doPriorRepay(BorrowRepayment borrowRepayment);

    /**
     * 更新标
     *
     * @param b
     */
    void addBorrow(Borrow b);

    /**
     * 标初审
     *
     * @param model
     */
    void verify(BorrowModel model, Operator operator);

    /**
     * 标初审-标准
     *
     * @param model
     */
    void verifyBz(BorrowModel model, Operator operator);

    /**
     * 更新标的状态
     *
     * @param id        标ID
     * @param status    目标状态
     * @param preStatus 前一状态
     * @return
     */
    void updateStatus(long id, int status, int preStatus);

    /**
     * 根据标Id获得标的详情
     *
     * @param id
     * @return
     */
    Borrow getBorrowById(long id);

    /**
     * 统计发标待审总数
     *
     * @param status
     * @return
     */
    int trialCount(int status);

    /**
     * 统计满标复审总数
     *
     * @param status
     * @return
     */
    int fullCount(int status);

    /**
     * 已成交的借款数 status=6,7,8
     *
     * @return
     */
    Object[] countByFinish();

    /**
     * 截标
     *
     * @param borrow
     */
    void stopBorrow(Borrow borrow);

    /**
     * 校验用户是否借款人
     *
     * @param borrowId
     * @param userId
     * @return
     */
    boolean isBorrowUser(long borrowId, long userId);

    /**
     * 获得非流转的标
     *
     * @param borrowId 标ID
     * @return Borrow
     */
    Borrow findNotFlow(long borrowId);

    boolean allowPublish(User user, BorrowModel model);

    /**
     * @param model
     * @param user
     * @param borrowMortgageList
     * @param delMortgageIds
     */
    void updateLoan(BorrowModel model, User user, Borrow oldBorrow, List<BorrowUpload> list,
                    List<BorrowMortgage> borrowMortgageList, long[] ids, long[] delMortgageIds);

    /**
     * 逾期垫付
     *
     * @param borrowRepayment
     */
    void overduePayment(BorrowRepayment borrowRepayment);

    /**
     * 查到当前ID所有BorrowUpload对象
     *
     * @param id 标ID
     * @return List<BorrowUpload>
     */
    List<BorrowUpload> findPicByBorrowId(long id);

    /**
     * 商家账户查看还款中的项目
     *
     * @param user
     * @return
     */
    List<BorrowModel> businessRepayment(User user);

    /**
     * 正在借款项目个数
     *
     * @param userId
     * @return
     */
    int findByStatusAndUserId(long userId, int status1, int status2);

    /**
     * 正在借款项目金额
     *
     * @param userId
     * @return
     */
    public double findAccountTotalByStatus(long userId, int status1, int status2);

    /**
     * 可借款标
     *
     * @return
     */
    public List<BorrowModel> investList(User user);

    /**
     * 前台分页
     *
     * @param model
     * @return
     */
    PageDataList<BorrowModel> getList(BorrowModel model);

    PageDataList<BorrowModel> getBorrowListForIndex(BorrowModel model);

    /**
     * 更新抵押物图片
     *
     * @param list   新上传的图片集合
     * @param delIds 删除的图片ID
     */
    void updatePic(List<BorrowUpload> list, long[] delIds);

    /**
     * 根据时间获取借款金额
     *
     * @param date
     * @return 借款金额
     */
    Double getBorrowAccountByDate(String date);

    /**
     * 成功发标个数
     */
    int count();

    /**
     * 获取当前担保公司正在担保的标的总个数
     *
     * @param userId
     * @return 标的总信息
     */
    int getGuaranteeingCount(long userId);

    /**
     * 获取当前担保公司正在担保的标的总金额信息
     *
     * @param userId
     * @return 标的总信息
     */
    double getGuaranteeingAccount(long userId);

    /**
     * 获取当前担保公司待登记的标的总个数
     *
     * @param userId
     * @return 标的总信息
     */
    int getNeedGuaranteeRegisteCount(long userId);

    /**
     * 获取当前担保公司待登记的标的总金额信息
     *
     * @param userId
     * @return 标的总信息
     */
    double getNeedGuaranteeRegisteAccount(long userId);

    /**
     * 获取当前担保公司逾期项目个数
     */
    int getOverdueCount(long userId);

    /**
     * 获取当前担保公司待登记的标的信息列表
     *
     * @param userId
     * @return 标的总信息
     */
    List<BorrowModel> getNeedGuaranteeRegisteList(long userId);

    /**
     * 获取当前用户的投标的信息列表
     *
     * @param userId
     * @return 标的总信息
     */
    boolean checkUserTenderList(long userId);

    /**
     * 获取当前用户的投标的信息列表
     *
     * @param userId
     * @return 标的总信息
     */
    boolean checkUserBorrowList(long userId);

    /**
     * 获取当前担保公司正在担保的标的信息列表
     *
     * @param model
     * @return 标的总信息
     */
    PageDataList<BorrowModel> getGuaranteeingList(BorrowModel model);

    /**
     * 获取当前担保公司逾期的标的信息列表
     *
     * @param model
     * @return 标的总信息
     */
    PageDataList<BorrowRepaymentModel> getOverdueGuaranteeList(BorrowModel model);

    /**
     * 获取当前担保公司已经代偿的标的信息列表
     *
     * @param model
     * @return 标的总信息
     */
    PageDataList<BorrowRepaymentModel> getCompensatedList(BorrowModel model);

    /**
     * 项目总数
     */
    int getAllCount();

    /**
     * 项目总金额
     */
    double getAllMomeny();

    /**
     * 逾期项目总数
     */
    int getAllOverduedCount();

    /**
     * 逾期项目金额
     */
    double getAllOverduedMomeny();

    /**
     * 根据标状态获取个数
     */
    int getCountByStatus(int status);

    /**
     * 根据标状态获取个数
     */
    double getMomenyByStatus(int status);

    /**
     * 已满标未复审的项目数量
     */
    int getVerifyFullCount();

    /**
     * 已满标未复审的项目金额
     */
    double getVerifyFullMomeny();

    /**
     * 逾期中项目总数
     */
    int getAllOverdueingCount();

    /**
     * 逾期中项目金额
     */
    double getAllOverdueingMomeny();

    /**
     * 根据时间获取借款用户个数
     *
     * @param date
     */
    int getBorrowCountByDate(String date);

    /**
     * 根据当前月得到分布图
     *
     * @return
     */
    double[] getDistributedByTypeAndDate(int type, String date);

    /**
     * 借款产品金额或人数分布
     *
     * @param type
     * @param date
     * @return
     */
    double[] getProductDistributedByTypeAndDate(int type, String date);

    /**
     * 标成交笔数或金额及同比值
     *
     * @param type
     * @param borrowType
     * @param date
     * @return
     */
    double[] getDealCountByTypeAndBorrowTypeAndDate(int type, int borrowType, String date);

    /**
     * 标成交占比
     *
     * @param type
     * @param date
     * @return
     */
    double[] getDealRatiosByTypeAndDate(int type, String date);

    /**
     * 平台交易额或笔数
     *
     * @param date
     * @return
     */
    double[][] getTurnoverByTypeAndDate(int type, String date);

    /**
     * 平台累计借款人
     *
     * @param date
     * @return
     */
    double[] getCumulativeBorrowByDate(String date);

    /**
     * 根据投资时间获取借款人基本信息
     *
     * @param date
     * @return
     */
    int[] getBorrowInfoByDate(String date);

    /**
     * 根据投资时间获取借款人所在地分布
     *
     * @param date
     * @return
     */
    Object[][] getBorrowAreaDistributedByDate(String date);

    /**
     * 获取尚未满标的最后一个借款标
     *
     * @return
     */
    Borrow getLastBorrow();

    /**
     * 新浪代收 异步回调成功 还款逻辑执行
     *
     * @param borrowRepayment
     */
    void notifySuccessRepay(BorrowRepayment borrowRepayment);

    /**
     * 根据标的id查询投标的人数
     */
    long getTenderUserCountByBorrowid(long borrowId);

    /**
     * 获取还款日期
     *
     * @param borrowModel
     * @param period
     */
    Date getRepayTime(BorrowModel borrowModel, int period);

    /**
     * 获取流标还款日期
     *
     * @param borrowModel
     * @param period
     */
    Date getFlowRepayTime(BorrowModel borrowModel, int period);

    /**
     * 获取管理费用比例
     *
     * @param borrowModel 借款标
     * @return 该标的管理费用比例
     * @author Kaiju Zhao
     */
    double getBorrowManageFeeRate(BorrowModel borrowModel);
}
